[LeetCode 363] Max Sum of Rectangle No Larger Than K
Problem description:
Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix such that its sum is no larger than k.
Note:
The input is an array of integers. Only the least significant 8 bits of each integer is used to store the data. This means each integer represents only 1 byte of data.
Example1:
1 | Given matrix = [ |
The answer is 2. Because the sum of rectangle [[0, 1], [-2, 3]] is 2 and 2 is the max number no larger than k (k = 2).
Note:
- The rectangle inside the matrix must have an area > 0.
- What if the number of rows is much larger than the number of columns?
问题描述:
给定一个非空的二位矩阵和一个整数K,找到矩阵中子矩阵和最大并且不超过k的最大值。
示例1:
1 | 给定矩阵 matrix = [ |
答案是2,因为矩形[[0, 1], [-2, 3]]和是2并且2 是不超过k(k=2)的最大值 。
Solution1:
这道题用纯暴力只能过95%左右,后面几个用例都会超时,所以在暴力的基础上稍微改进一下即可通过。(但不是最优解,复杂度为O(N2M2))
用一个新矩阵保存计算值,每个值表示从点(0,0)到(i,j)的和,则计算(x1,y1)到(x2,y2)的值有以下四种情况:
- x1-1<0 && y1-1<0: 说明(x1,y1)即为(0,0)点,直接返回存储矩阵中s[x2][y2]的值
x1-1>=0 && y1-1<0: 说明y1=0,
1
2
3
4
5
61 2 3 4
-------
5 6 7 8
0 1 2 9
-------
计算从(1,0)到(3,3)的值则返回s[x2][y2]-s[x1-1][y2]
x1-1<0 &&="" y1-1="">=0: 说明x1=0, 0>
1
2
3
4
51|2 3 4|
5|6 7 8|
0|1 2 9|
计算从(0,1)到(3,3)的值
则返回s[x2][y2]-s[x2][y1-1]
x1-1>=0 && y1-1>=0:
1
2
3
4
51 2 3 4
-------
5|6 7 8|
0|1 2 9|
-------
则返回s[x2][y2]-(s[x1-1][y2]+s[x2][y1-1]-s[x1-1][y1-1])
遍历子矩阵用四层循环即可解决。
Code:
1 | class Solution { |
Solution2:动态递归解法(学习后补充)
首先使用动态规划解法,这道题目可以拆分成两道题。
第一点是求矩阵子矩阵最大和的动态规划思想,参考视频链接。
具体思想就是,按列扫描累加每一列然后求最大值,这样就转换为一维数组子数组求最大和的问题,这是一个简单的动态规划,dp[i]=max(dp[i-1],array[i]);
第二点就是一维数组子数组最大和有可能大于给定的k,所以问题转换为求一维数组子数组和不大于k的最大值:
通过累加和可以求得任意区间的和,例如,cum数组为累加和数组,cum[i]表示从cum[0]到cum[i]的和,则区间(i,j)的和可表示为cum[j]-cum[i-1];
这里还要借助TreeSet因为treeset中ceiling方法可以求出大于或等于给定的元素的最小元素,也就是说我们在累加过程中去比较max和set.ceiling(sum-k)的大小即可,由于treeset查询这一步时间复杂度是O(logn),所以总的时间复杂度是O(N2*M*log(M)),如果列数远远大于行数,可以按照行扫描。
Code:
1 | class Solution { |